package com.jorado.metrics.servlet;

import com.jorado.metrics.discovery.ZookeeperDiscovery;
import com.jorado.metrics.jvm.DefaultExports;
import com.jorado.metrics.util.ApplicationHelp;
import com.jorado.metrics.util.EnvUtils;
import io.prometheus.client.exporter.MetricsServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Metrics {

    public static final Logger logger = LoggerFactory.getLogger(Metrics.class);

    // 单例模式
    private static Metrics Instance = null;

    private boolean started = false;
    private int port = 9191;
    private String proxy = "metrics-proxy.zpidc.com/%s/%s";
    //    private String zookeeper = "metrics-zookeeper.zpidc.com:2181";
    private String zookeeper = "172.30.25.80,172.30.25.81,172.30.25.82";

    public static void start() {
        if (Instance == null) {
            Instance = new Metrics();
        }
    }

    public static void start(int port, String zookeeper, String proxy) {
        if (Instance == null) {
            Instance = new Metrics(port, zookeeper, proxy);
        }
    }

    public Metrics() {
        String configPort = System.getProperty("metrics.port");
        if (configPort != null && !"".equals(configPort)) {
            this.port = Integer.parseInt(configPort);
        }
        String zookeeper = System.getProperty("metrics.discovery");
        String proxyHost = System.getProperty("metrics.proxy");
        logger.info("metrics getProperty, zookeeper: {}, proxy: {}", zookeeper, proxyHost);
        if (zookeeper != null && !"".equals(zookeeper)) {
            this.zookeeper = zookeeper;
        }
        if (proxyHost != null && !"".equals(proxyHost)) {
            this.proxy = proxyHost;
        }
        this.startHandler();
    }


    public Metrics(String zookeeper) {
        this(zookeeper, null);
    }

    public Metrics(String zookeeper, String proxy) {
        this(9191, zookeeper, proxy);
    }

    public Metrics(int port, String zookeeper, String proxy) {
        logger.info("metrics - constructor, port: {}, zookeeper: {}, proxy: {}", port, zookeeper, proxy);
        if (port > 0) {
            this.port = port;
        }
        if (zookeeper != null && !"".equals(zookeeper)) {
            this.zookeeper = zookeeper;
        }
        if (proxy != null && !"".equals(proxy)) {
            this.proxy = proxy;
        }
        this.startHandler();
    }

    private synchronized void startHandler() {
        if (!this.started) {

            DefaultExports.initialize();
            logger.info("metrics - startHandler, listen: {}, appName: {}", this.port, ApplicationHelp.getAppName());
            Server server = new Server(this.port);
            ServletContextHandler context = new ServletContextHandler();
            context.setContextPath("/");
            server.setHandler(context);
            context.addServlet(new ServletHolder(new MetricsServlet()), "/metrics");

            try {
                server.start();
                this.started = true;
            } catch (Exception e) {
                logger.error("metrics - startHandler, error: {}", e.getMessage(), e);
            }

            if (!EnvUtils.islocalEnv() || "true".equals(System.getProperty("metrics.enable"))) {
                String proxyHost = String.format(this.proxy, ApplicationHelp.getCluster(), ApplicationHelp.getAppName());
                String zookeeperDiscovery = String.format(this.zookeeper, ApplicationHelp.getCluster());
                logger.info("metrics - regiter start, zookeeper: {}, proxy: {}", zookeeperDiscovery, proxyHost);
                if (zookeeperDiscovery != null && !"".equals(zookeeperDiscovery)) {
//                    discoverByZookeeper(zookeeperDiscovery, proxyHost, ApplicationHelp.getIpAddress(), this.port);
                    new RegisterThread(zookeeperDiscovery, proxyHost, ApplicationHelp.getIpAddress(), this.port).start();
                }
            } else {
                logger.info("metrics - regiter is unEnable, islocalEnv: {}, metricsEnable: {}", EnvUtils.islocalEnv(), System.getProperty("metrics.enable"));
            }
        }
    }

    class RegisterThread extends Thread {
        private String zookeeper;
        private String proxy;
        private String host;
        private int port;

        public RegisterThread(String zookeeper, String proxy, String host, int port) {
            this.zookeeper = zookeeper;
            this.proxy = proxy;
            this.host = host;
            this.port = port;
        }

        @Override
        public void run() {
            new ZookeeperDiscovery(zookeeper.replaceFirst("zookeeper:", ""), proxy, host, port, "");
        }
    }

}
